﻿using System;
using System.Threading;
using System.Windows.Input;
using NUnit.Framework;
using Present.Commands.Async.Actions;
using Present.Commands.Async.Actions.Decorators;
using Rhino.Mocks;

namespace Present.Commands.Tests.Decorators
{
    public abstract class AsyncActionDecoratorTestCaseBase<TDecorator, TParameter, TResult> : TestCase 
        where TDecorator : AsyncActionDecorator<TParameter, TResult>
    {
        protected IAsyncAction<int, int> Inner;
        protected TDecorator Decorator;

        public override void Setup()
        {
            base.Setup();
            Inner = MockRepository.GenerateStub<IAsyncAction<int, int>>();
            Decorator = CreateDecorator();
        }

        protected abstract TDecorator CreateDecorator();
        protected abstract TParameter GetParameter();
        protected abstract TResult GetResult();

        [Test]
        public void ErrorHandlerCalledOnInnerTargetOnError()
        {
            var exception = new Exception();
            Decorator.HandleError(exception);
            Inner.AssertWasCalled(x => x.HandleError(exception));
        }

        [Test]
        public void PrepareWorkCalledOnInnerTarget()
        {
            Decorator.PrepareWork(GetParameter());
            Inner.AssertWasCalled(x => ((IAsyncAction<TParameter, TResult>)x).PrepareWork(GetParameter()));
        }


        [Test]
        public void SuccessHandlerCalledOnInnerTargetOnSuccess()
        {

            Decorator.HandleSuccess(GetResult());
            Inner.AssertWasCalled(x => x.HandleSuccess(1));
        }

    }


   

}